/**
 * @file boards\stm32l051kx\bsp\bsp_key1.c
 *
 * Copyright (C) 2023
 *
 * bsp_key1.c is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */

/*---------- includes ----------*/
#include "bsp_relay.h"
#include "cpu.h"
#include "gd32f30x_gpio.h"
#include "gpio_group.h"

/*---------- macro ----------*/
#define RCC_ALL_KEY (RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO)
#define GPIO_PORT_RELAY1 GPIOC
#define GPIO_PIN_RELAY1O GPIO_PIN_10
#define GPIO_PIN_RELAY1C GPIO_PIN_10

#define GPIO_PORT_RELAY2 GPIOC
#define GPIO_PIN_RELAY2O GPIO_PIN_11
#define GPIO_PIN_RELAY2C GPIO_PIN_11

#define GPIO_PORT_RELAY3 GPIOC
#define GPIO_PIN_RELAY3C GPIO_PIN_12
#define GPIO_PIN_RELAY3O GPIO_PIN_12

#define GPIO_PORT_ZERO GPIOC
#define GPIO_PIN_ZERO GPIO_PIN_8

#define RELAY1_STA 0x01 //
#define RELAY2_STA 0x02 //
#define RELAY3_STA 0x04 //
#define RELAY4_STA 0x08 //
/*---------- type define ----------*/
typedef enum {
    RELAY_ON = 1,
    RELAY_OFF = 0,
} RELAYx_STA;
typedef enum {
    RELAYx_0 = 1,
    RELAYx_1,
    RELAYx_2,
    RELAYx_3,
    RELAYx_4,
    RELAYx_A,
} RELAYx_NUM; //
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
static bool bsp_init(void);
static void bsp_deinit(void);
static unsigned char bsp_get(unsigned char xx);
static void bsp_set(unsigned char xx, unsigned char val);

/*---------- variable ----------*/
static gpio_group_describe_t relay = {
    .group_name = "relay",
    .ops.init = bsp_init,
    .ops.deinit = bsp_deinit,
    .ops.get = bsp_get,
    .ops.set = bsp_set,
    .group_sta = 0,
    .group_num_max = 3,
};
DEVICE_DEFINED(relay, gpio_group, &relay);

/*---------- function ----------*/
static bool bsp_init(void) {
  /* ��GPIOʱ�� */
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_AF);

    gpio_init(GPIO_PORT_RELAY1, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY1C);
    gpio_init(GPIO_PORT_RELAY2, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY2C);
    gpio_init(GPIO_PORT_RELAY3, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY3C);
    gpio_init(GPIO_PORT_ZERO, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,
        GPIO_PIN_ZERO);

    return true;
}

static void bsp_deinit(void) {
  // ��1������GPIOʱ��
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOB);

    rcu_periph_clock_enable(RCU_AF);

    gpio_init(GPIO_PORT_RELAY1, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY1C);
    gpio_init(GPIO_PORT_RELAY2, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY2C);
    gpio_init(GPIO_PORT_RELAY3, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ,
        GPIO_PIN_RELAY3C);
    gpio_init(GPIO_PORT_ZERO, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_ZERO);
}
static unsigned char bsp_CheckZeroLin(void) {
    unsigned char rt;
    if ((gpio_input_bit_get(GPIO_PORT_ZERO, GPIO_PIN_ZERO)) == 0) {
        udelay(50);
        if ((gpio_input_bit_get(GPIO_PORT_ZERO, GPIO_PIN_ZERO)) == 0) {
            rt = 1;
            return rt;
        }
    }
    rt = 0;
    return rt;
}
static void bsp_set(unsigned char xx, unsigned char val) {
    unsigned char i = 0;
    if (val == RELAY_OFF) {
        if (xx == RELAYx_0) {
            relay.group_sta = relay.group_sta & (~RELAY1_STA);
            gpio_bit_reset(GPIO_PORT_RELAY1, GPIO_PIN_RELAY1C);
        }
        else if (xx == RELAYx_1) {
            relay.group_sta = relay.group_sta & (~RELAY2_STA);
            gpio_bit_reset(GPIO_PORT_RELAY2, GPIO_PIN_RELAY2C);
        }
        else if (xx == RELAYx_2) {
            relay.group_sta = relay.group_sta & (~RELAY2_STA);
            gpio_bit_reset(GPIO_PORT_RELAY3, GPIO_PIN_RELAY3C);
        }

    }
    else if (val == RELAY_ON) {
        if (xx == RELAYx_0) {
            relay.group_sta = relay.group_sta | RELAY1_STA;
            gpio_bit_set(GPIO_PORT_RELAY1, GPIO_PIN_RELAY1C);
        }
        else if (xx == RELAYx_1) {
            relay.group_sta = relay.group_sta | RELAY2_STA;
            gpio_bit_set(GPIO_PORT_RELAY2, GPIO_PIN_RELAY2C);
        }
        else if (xx == RELAYx_2) {
            relay.group_sta = relay.group_sta | RELAY3_STA;
            gpio_bit_set(GPIO_PORT_RELAY3, GPIO_PIN_RELAY3C);
        }
    }
}

static unsigned char bsp_get(unsigned char xx) {
    unsigned char Tgroup_sta = 0;

    Tgroup_sta = ((relay.group_sta & 0x0F) >> xx) & 0x01;

    return relay.group_sta;
}
